﻿using System;
using System.Collections.Generic;
using System.Linq;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.Entities;
using Sustainalytics.ESG.Entities;
using Sustainalytics.Utils;

namespace Sustainalytics.ESGRatings.BusinessLogic.Models
{
    public class ESGRpIndicator : IEntity, IHasUniverseIds
    {
        public int AnswerCategory { get; set; }
        public string AnswerCategoryDescription { get; set; }
        public string Cluster { get; set; }
        public string Code { get; set; }
        //EsgRpIndicatorScoreDto
        public string Comments { get; set; }
        //EsgRpControversyDto
        public int ControversyLevel { get; set; }
        //EsgRpControversyDto

        public List<DataHistory> DataTable { get; set; }
        public IEnumerable<string> EventIndicators { get; set; }
        public Guid Id { get; set; }
        public bool IsControversyIndicator { get; set; }
        public string Name { get; set; }
        public int? OutlookScore { get; set; }
        public double? RawScore { get; set; }
        public Guid ThemeId { get; set; }
        public string ThemeName { get; set; }
        public List<Tickbox> Tickboxes { get; set; }
        public int? Trend { get; set; }
        public List<int> UniverseIds { get; set; }
        //EsgRpIndicatorScoreDto
        public double? Weight { get; set; }
        public double? WeightedScore { get; set; }

        public static ESGRpIndicator FromDatabaseObject<T>(T indicator) where T : IEntity
        {
            if (indicator == null)
            {
                throw new ArgumentNullException("indicator");
            }

            if (typeof(T) == typeof(EventIndicator))
            {
                var eventIndicator = indicator as EventIndicator;
                if (eventIndicator != null)
                {
                    return FromEventsIndicators(eventIndicator);
                }
            }


            if (typeof(T) == typeof(RPControversyIndicator))
            {
                var controversyIndicator = indicator as RPControversyIndicator;
                if (controversyIndicator != null)
                {
                    return FromControversyIndicators(controversyIndicator);
                }
            }

            if (typeof(T) != typeof(RPIndicatorExtended))
            {
                return null;
            }
            var standardIndicator = indicator as RPIndicatorExtended;
            return standardIndicator != null ? FromStandardIndicators(standardIndicator) : null;
        }

        private static ESGRpIndicator FromControversyIndicators(RPControversyIndicator controversyIndicator)
        {
            return new ESGRpIndicator
            {
                Id = controversyIndicator.Id,
                Name = controversyIndicator.Template.Name,
                Code = controversyIndicator.Template.Number,
                ThemeId = controversyIndicator.Template.ThemeId,
                ThemeName = controversyIndicator.Template.ThemeName,
                Cluster = controversyIndicator.Template.IndicatorCategory,
                IsControversyIndicator = true,
                AnswerCategory = controversyIndicator.AnswerCategory,
                AnswerCategoryDescription = controversyIndicator.AnswerCategoryText,
                EventIndicators =
                    controversyIndicator.EventIndicators.IsNullOrEmpty()
                        ? Enumerable.Empty<string>()
                        : controversyIndicator.EventIndicators.Select(x => x.Name).ToList(),
                OutlookScore = controversyIndicator.OutlookScore,
                ControversyLevel = controversyIndicator.AnswerCategory,
                Weight = controversyIndicator.Weight,
                WeightedScore = controversyIndicator.WeightedScore,
                RawScore = controversyIndicator.AnswerCategoryScore,
                Trend = controversyIndicator.Trend,
                UniverseIds = controversyIndicator.UniverseIds
            };
        }

        private static ESGRpIndicator FromEventsIndicators(EventIndicator eventIndicator)
        {
            return new ESGRpIndicator
            {
                Id = eventIndicator.Id,
                Name = eventIndicator.ControversyIndicatorName,
                Code = eventIndicator.ControversyIndicatorNumber,
                //ThemeId = eventIndicator.ThemeId,
                //ThemeName = eventIndicator.ThemeName,
                //Cluster = eventIndicator.IndicatorCategoryName,
                IsControversyIndicator = true,
                AnswerCategory = eventIndicator.AnswerCategory,
                AnswerCategoryDescription = eventIndicator.AnswerCategoryText,
                EventIndicators = new[] {eventIndicator.Name},
                OutlookScore = eventIndicator.OutlookScore,
                ControversyLevel = eventIndicator.AnswerCategory,
                //Weight = eventIndicator.Weight,
                //WeightedScore =eventIndicator.WeightedScore,
                RawScore = eventIndicator.AnswerCategoryScore,
                //Trend =eventIndicator.Trend
                UniverseIds = eventIndicator.UniverseIds
            };
        }

        private static ESGRpIndicator FromStandardIndicators(RPIndicatorExtended standardIndicator)
        {
            return new ESGRpIndicator
            {
                Id = standardIndicator.Id,
                Name = standardIndicator.Template.Name,
                Code = standardIndicator.Template.Number,
                ThemeId = standardIndicator.Template.ThemeId,
                ThemeName = standardIndicator.Template.ThemeName,
                Cluster = standardIndicator.Template.IndicatorCategory,
                IsControversyIndicator = standardIndicator.Template.IsControversyIndicator,
                AnswerCategoryDescription = standardIndicator.SelectedAnswer.Text,
                Comments = standardIndicator.Comments,
                Tickboxes = standardIndicator.Tickboxes,
                DataTable = standardIndicator.DataTable,
                Weight = standardIndicator.Weight,
                WeightedScore = standardIndicator.WeightedScore,
                RawScore = standardIndicator.SelectedAnswer.Score,
                Trend = standardIndicator.Trend,
                UniverseIds = standardIndicator.UniverseIds
            };
        }
    }
}